<!DOCTYPE html>
<html lang="zh-cn" >
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta
      name="author"
      content="awesome404"
    />
      
    <title>Vue2组件 ｜ 鹊木笔记</title>
    
    
    
    <meta name="description" content="什么是组件化 复杂问题的处理方式 任何一个人处理信息的逻辑能力都是有限的 所以，当面对一个非常复杂的问题时，我们不太可能一次性搞定一大堆的内容 如果将一个复杂的问题，拆分成多个可以处理的小问题，再将其放在整体" />
      
    <meta
      name="keywords"
      content="Blog, 程序员, 前端"
    />
      <link
    rel="shortcut icon" href="https://awesome404.gitee.io/images/favicon.ico" />

    <link
      rel="stylesheet"
      type="text/css"
      media="screen"
      href="https://awesome404.gitee.io/css/normalize.css"
    />
    <link
      rel="stylesheet"
      type="text/css"
      media="screen"
      href="https://cdn.jsdelivr.net/npm/animate.css@4.1.0/animate.min.css"
    />
    <link rel="stylesheet" type="text/css" media="screen" href="https://awesome404.gitee.io/css/zozo.css" />
    <link
      rel="stylesheet"
      type="text/css"
      media="screen"
      href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css"
    />
    <link rel="stylesheet" type="text/css" media="screen" href="https://awesome404.gitee.io/css/highlight.css" />

    
    
  </head>
</html>


<body>
    <div class="main animate__animated animate__fadeInDown">
        
<div class="nav_container animated fadeInDown">
  <div class="site_nav" id="site_nav">
    <ul>
      
      <li>
        <a href="/">首页</a>
      </li>
      
      <li>
        <a href="/posts/">归档</a>
      </li>
      
      <li>
        <a href="/tags/">标签</a>
      </li>
      
      <li>
        <a href="/about/">关于</a>
      </li>
      
    </ul>
  </div>
  <div class="menu_icon">
    <a id="menu_icon">
      <i class="ri-settings-line"></i>
    </a>
  </div>
</div>

        <div class="header animated fadeInDown">
  <div class="site_title_container">
    <div class="site_title">
      <h1>
        <a href="https://awesome404.gitee.io">
          <span>鹊木笔记</span>
        </a>
      </h1>
    </div>
    <div class="description">
      <p class="sub_title">
        前端菜鸡的自我修养
      </p>
      <div class="my_socials">
         
        <a href="https://github.com/404Awesome" title="github" target="_blank"
          ><i class="ri-github-fill"></i
        ></a>
         
        <a
          href="https://awesome404.gitee.io/index.xml"
          type="application/rss+xml"
          title="rss"
          target="_blank"
          ><i class="ri-rss-fill"></i
        ></a>
      </div>
    </div>
  </div>
</div>

        <div class="content">
            <div class="post_page">
                <div class="post animate__animated animate__fadeInDown">
                    <div class="post_title post_detail_title">
                        <h2><a href='/posts/vue2%E7%BB%84%E4%BB%B6/'>Vue2组件</a></h2>
                        <span class="date">2020.04.13</span>
                    </div>
                    <div class="post_content markdown"><h1 id="什么是组件化">什么是组件化</h1>
<h3 id="复杂问题的处理方式">复杂问题的处理方式</h3>
<ol>
<li>任何一个人处理信息的逻辑能力都是有限的</li>
<li>所以，当面对一个非常复杂的问题时，我们不太可能一次性搞定一大堆的内容</li>
<li>如果将一个复杂的问题，拆分成多个可以处理的小问题，再将其放在整体当中，你会发现大的问题也会迎刃而解</li>
</ol>
<h3 id="组件化思想">组件化思想</h3>
<ol>
<li>如果我们将一个页面中所有的处理逻辑全部放在一起， 处理起来就会变得非常复杂，而且不利于后续的管理一级扩展</li>
<li>但如果，我们将一个页面拆分成一个个小的功能块，每个功能块完成属于自己的这部分独立的功能，那么之后整个页面的管理和维护就变的非常容易</li>
</ol>
<h1 id="vue-组件化思想">Vue 组件化思想</h1>
<h3 id="介绍">介绍</h3>
<ol>
<li>它提供了一种抽象，让我们可以开发出一个个独立可复用的小组件来构造我们的应用</li>
<li>组件化是 Vue.js 中的重要思想</li>
<li>任何的应用都会被抽象成一颗组件树，如下</li>
</ol>
<img src="/img/post/vue2/组件树.png">
<h3 id="组件化思想的应用">组件化思想的应用</h3>
<ol>
<li>有了组件化的思想，我们在之后的开发中就要充分的利用它</li>
<li>尽可能的将页面拆分成一个个小的，可复用的组件</li>
<li>这样让我们的代码更加方便组织和管理，并且扩展性也更强</li>
</ol>
<h1 id="注册组件基本步骤">注册组件基本步骤</h1>
<p>组件的使用分成以下三个步骤</p>
<ol>
<li>
<p>创建组件构造器</p>
<blockquote>
<p>通过 Vue.extend( ) 创建组件构造器</p>
</blockquote>
</li>
<li>
<p>注册组件</p>
<blockquote>
<p>通过 Vue.component( ) 注册组件</p>
</blockquote>
</li>
<li>
<p>使用组件</p>
<blockquote>
<p>根据注册的标签名进行使用</p>
</blockquote>
</li>
</ol>
<p>例子如下</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">cpn</span><span class="p">&gt;&lt;/</span><span class="nt">cpn</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">myCpn</span> <span class="o">=</span> <span class="nx">Vue</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">template</span><span class="o">:</span> <span class="sb">`
</span></span></span><span class="line"><span class="cl"><span class="sb">		&lt;div&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">			&lt;h1&gt;Hello Vue&lt;/h1&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">			&lt;p&gt;Lorem ipsum dolor sit&lt;/p&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">		&lt;/div&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">	`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="nx">Vue</span><span class="p">.</span><span class="nx">component</span><span class="p">(</span><span class="s2">&#34;cpn&#34;</span><span class="p">,</span> <span class="nx">myCpn</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">temp</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vue</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">el</span><span class="o">:</span> <span class="s2">&#34;main&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>经过上述操作便可以在页面中看到 Hello Vue 等字样，其中 Vue.extend 是创建组件，Vue.component 是用来注册组件的，还有就是组件构造器中 template 属性可以配合模板字面量，这些 HTML 代码需要在一个根节点下面，否则解析失败，上述代码中 div 就是一个根节点，此外 Vue.component( ) 方法内有两个参数，第一个是注册的标签名，第二个是组件构造器的引用，除了上面代码的那种写法之外，还有语法糖格式的，可以将组件构造器的创建与注册进行简写，如下</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">Vue</span><span class="p">.</span><span class="nx">component</span><span class="p">(</span><span class="s2">&#34;cpn&#34;</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">template</span><span class="o">:</span> <span class="sb">`
</span></span></span><span class="line"><span class="cl"><span class="sb">		&lt;div&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">			&lt;h1&gt;Hello Vue&lt;/h1&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">		&lt;/div&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">	`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>其中注册组件还分为</p>
<ol>
<li>
<p>全局注册</p>
<blockquote>
<p>如上所示代码的 Vue.component 注册组件的方式，是全局注册，进过全局注册的组件可以在所有组件中直接使用</p>
</blockquote>
</li>
<li>
<p>局部注册</p>
<blockquote>
<p>通过局部注册的组件，只能在当前组件下使用，使用属性 components 进行注册，注意是复数，如下</p>
</blockquote>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">myCpn</span> <span class="o">=</span> <span class="nx">Vue</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">template</span><span class="o">:</span> <span class="sb">`
</span></span></span><span class="line"><span class="cl"><span class="sb">		&lt;div&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">			&lt;h1&gt;Hello Vue&lt;/h1&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">			&lt;p&gt;Lorem ipsum dolor sit&lt;/p&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">		&lt;/div&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">	`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">temp</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vue</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">el</span><span class="o">:</span> <span class="s2">&#34;main&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">data</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">content</span><span class="o">:</span> <span class="s2">&#34;Hello World&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">components</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">cpn</span><span class="o">:</span> <span class="nx">myCpn</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div></li>
</ol>
<blockquote>
<p>需要注意的是注册组件所使用的标签名称应该全部为小写形式，可以使用连字符，不能使用驼峰写法，因为 HTML 无法解析</p>
</blockquote>
<h3 id="注册组件语法糖">注册组件语法糖</h3>
<h4 id="注册全局组件">注册全局组件</h4>
<p>可以简写为以下代码</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">Vue</span><span class="p">.</span><span class="nx">component</span><span class="p">(</span><span class="s2">&#34;cpn&#34;</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">template</span><span class="o">:</span> <span class="sb">`
</span></span></span><span class="line"><span class="cl"><span class="sb">    	&lt;div&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">    		&lt;h1&gt;Hello World&lt;/h1&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">    	&lt;/div&gt;`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>虽然看起来是没有用到 Vue.extend( )，但是底层还是调用的 Vue.extend( ) 方法实现的</p>
<h4 id="注册局部组件">注册局部组件</h4>
<p>可以简写为以下代码</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">temp</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vue</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">el</span><span class="o">:</span> <span class="s2">&#34;main&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">data</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">content</span><span class="o">:</span> <span class="s2">&#34;Hello Vue&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">components</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">cpn</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">template</span><span class="o">:</span> <span class="sb">`
</span></span></span><span class="line"><span class="cl"><span class="sb">				&lt;div&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">					&lt;h1&gt;Hello Vue&lt;/h1&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">				&lt;/div&gt;	`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>以上两种方式注册的组件内 template 模板属性后面的 HTML 代码看起来有些臃肿，有两种方式可以组件模板与 Js 代码相分离，如下</p>
<h3 id="模板分离">模板分离</h3>
<h4 id="script">script</h4>
<p>使用 script 标签创建组件模板，如下</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text/x-template&#34;</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;myCpn&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl">     	<span class="o">&lt;</span><span class="nx">h1</span><span class="o">&gt;</span><span class="nx">Hello</span> <span class="nx">Vue</span><span class="o">&lt;</span><span class="err">/h1&gt;</span>
</span></span><span class="line"><span class="cl">     <span class="o">&lt;</span><span class="err">/div&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">temp</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vue</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">el</span><span class="o">:</span> <span class="s2">&#34;main&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">data</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">content</span><span class="o">:</span> <span class="s2">&#34;Hello World&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">components</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">cpn</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">template</span><span class="o">:</span> <span class="s2">&#34;#myCpn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>以上是使用注册局部组件的方式演示的，全局组件如上形式，在 template 属性后面跟上组件模板的 id 名</p>
<h4 id="template">template</h4>
<p>使用 template 标签创建组件模板和使用 script 一样，只不过换了个标签，如下</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;myCpn&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>Hello Vue<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Js 代码同使用 script 标签模板的一样，在 template 属性后面跟上 id 名</p>
<h1 id="步骤解析">步骤解析</h1>
<h3 id="1-vueextend-">1. Vue.extend( )</h3>
<blockquote>
<p>调用 Vue.extend( ) 创建的是一个组件构造器</p>
<p>通常在创建组件构造器时，传入 template 代表我们自定义的组件模板</p>
<p>该模板就是在使用组件的地方，要显示的 HTML 代码</p>
<p>事实上，这种写法在 Vue2.x 的文档中几乎已经看不到了，他会直接使用语法糖格式，但是还是会有很多资料提到这种方式，而且这种方式是学习后面方式的基础</p>
</blockquote>
<h3 id="2-vuecomponent-">2. Vue.component( )</h3>
<blockquote>
<p>调用 Vue.component( ) 是将刚才的组件构造器注册为一个组件，并且给它起一个组件的标签名称</p>
<p>所以需要传递的两个参数：1. 注册组件的标签名 2. 组件构造器 {全局注册}，局部注册则不需要</p>
</blockquote>
<h3 id="3-使用">3. 使用</h3>
<blockquote>
<p>如果是全局组件，可以在所有使用 Vue 实例管理的 Dom 元素下使用，如果为局部组件，就必须在注册 Vue 实例对应的 Dom 下使用</p>
</blockquote>
<h1 id="组件数据的存放">组件数据的存放</h1>
<p>目前来看我们创建的组件，内部使用的数据都是写死的，如果我们想要通过变量来获取数据，该如何操作，其实组件内不止有 template 属性，还可以有 data methods 等，但是需要注意的是 data 并非是一个对象类型的，而是一个工厂函数，通过这个函数返回一个带有数据的对象，以全局组件为例，如下</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">Vue</span><span class="p">.</span><span class="nx">component</span><span class="p">(</span><span class="s2">&#34;cpn&#34;</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">template</span><span class="o">:</span> <span class="sb">`
</span></span></span><span class="line"><span class="cl"><span class="sb">		&lt;div&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">			&lt;h1&gt; {{content}} &lt;/h1&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">		&lt;/div&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">	`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">data</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">content</span><span class="o">:</span> <span class="s2">&#34;Hello Vue&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">};</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>为什么需要这样做，先看如下代码</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">cpn</span><span class="p">&gt;&lt;/</span><span class="nt">cpn</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">cpn</span><span class="p">&gt;&lt;/</span><span class="nt">cpn</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">cpn</span><span class="p">&gt;&lt;/</span><span class="nt">cpn</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>当使用多个同样组件时，若 data 是对象类型，则这些组件使用的是数据是指向一个内存地址的，也就是操作的都是一个对象，这样一来，就无法保证它们之间的数据互相独立，但是使用函数的话，每使用一次组件，都会由函数返回一个内存地址不同的对象，这样一来，不管使用几次组件，都不会相互影响了</p>
<h1 id="父组件和子组件">父组件和子组件</h1>
<h4 id="在前面我们看到了组件树">在前面我们看到了组件树</h4>
<ol>
<li>组件与组件之间存在着层级关系</li>
<li>而其中一种非常常见的关系就是父子组件关系</li>
</ol>
<p>我们还可以创建多个组件，让他们有顺序的嵌套在一起，然后注册父级组件，然后展示到页面，注册在组件内的组件，为所在组件的子组件，而所在的组件为父组件，可以嵌套多层 ，例子如下</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">Vue</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">template</span><span class="o">:</span> <span class="sb">`
</span></span></span><span class="line"><span class="cl"><span class="sb">		&lt;div&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">			&lt;h2&gt;Hello Son&lt;/h2&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">		&lt;/div&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">	`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">parent</span> <span class="o">=</span> <span class="nx">Vue</span><span class="p">.</span><span class="nx">extend</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">template</span><span class="o">:</span> <span class="sb">`
</span></span></span><span class="line"><span class="cl"><span class="sb">		&lt;div&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">			&lt;h1&gt;Hello Father&lt;/h1&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">			&lt;son&gt;&lt;/son&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">		&lt;/div&gt;
</span></span></span><span class="line"><span class="cl"><span class="sb">	`</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">components</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">son</span><span class="o">:</span> <span class="nx">child</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">temp</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vue</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">el</span><span class="o">:</span> <span class="s2">&#34;main&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">data</span><span class="o">:</span> <span class="p">{},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">components</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">cpn</span><span class="o">:</span> <span class="nx">parent</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>从上代码看的出来，parent 中定义了 components 属性，然后通过 components 属性将 child 子组件注册成局部组件，然后又将 parent 注册到根组件上，也就是 Vue 实例，我们可以把 Vue 实例当做根组件</p>
<h1 id="父子组件通信">父子组件通信</h1>
<p>一般情况下，子组件是无法访问父组件的 data 数据的</p>
<p>但是，在开发中，往往一些数据是需要从上层传递到下层的</p>
<ol>
<li>比如在一个页面，我们从服务器请求到了很多数据</li>
<li>其中一部分数据，并非是我们整个页面的大组件来展示的，而是需要下面的子组件进行展示</li>
<li>这个时候，并不会让子组件再次发送一个网络请求，而是直接让大组件( 父组件)将数据传递给小组件(子组件)</li>
</ol>
<p>如何进行父子组件之间的通信，如下</p>
<ol>
<li>通过 props 向子组件传递数据</li>
<li>通过事件向父组件发送信息</li>
</ol>
<img src="/img/post/vue2/父子通信.png">
<h3 id="父传子">父传子</h3>
<p>可以使用 props 属性，这个属性有两种方式，一种是数组，一种是对象，为了方便我们在一个 Vue 实例中注册局部组件</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">cpn</span> <span class="na">v-bind:mytext</span><span class="o">=</span><span class="s">&#34;content&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">cpn</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;myCpn&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span>{{mytext}}<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">temp</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vue</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">el</span><span class="o">:</span> <span class="s2">&#34;main&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">data</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">content</span><span class="o">:</span> <span class="s2">&#34;Hello World&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">components</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">cpn</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">template</span><span class="o">:</span> <span class="s2">&#34;#myCpn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">props</span><span class="o">:</span> <span class="p">[</span><span class="s2">&#34;mytext&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>上面在组件实例中使用 props 属性，值是一个数组类型，但是数组类型的并不常用，常用的是对象类型，这里我们将定义好的属性 mytext，在自己组件上使用，还是使用了 v-bind 指令，将父元素上的变量 content 的值，传了过来，这里若只想传过来一个普通字符串，就不必使用 v-bind 指令了</p>
<p>对象类型还分为两种，如下</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">temp</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vue</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">el</span><span class="o">:</span> <span class="s2">&#34;main&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">data</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">content</span><span class="o">:</span> <span class="s2">&#34;Hello World&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">components</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">cpn</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">template</span><span class="o">:</span> <span class="s2">&#34;#myCpn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">props</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">mytext</span><span class="o">:</span> <span class="nb">String</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>对象内属性 mytext 对象的值是对 props 做数据验证，关于这个后面在做讲解，这个 mytext 变量还可以是一个对象形式的，如果是对象形式的话，还能设置默认值等， 如下</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">temp</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vue</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">el</span><span class="o">:</span> <span class="s2">&#34;main&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">data</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">content</span><span class="o">:</span> <span class="s2">&#34;Hello World&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">components</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">cpn</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">template</span><span class="o">:</span> <span class="s2">&#34;#myCpn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">props</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">mytext</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">type</span><span class="o">:</span> <span class="nb">String</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="k">default</span><span class="o">:</span> <span class="s2">&#34;Hello Vue&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">required</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>其中 type 属性是对 props 做数据验证，default 是设置默认值，若没有传值过来，就使用默认值，required 属性是表示是否必需为该变量传值，属性值是布尔值，true 是必传，false 则不是，默认是 false</p>
<p>如果 type 属性是 Array / Object 时，默认值需要通过函数返回，如下</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">myarr</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">type</span><span class="o">:</span> <span class="nb">String</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="k">default</span> <span class="p">(){</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="p">[</span><span class="s1">&#39;value1&#39;</span><span class="p">,</span> <span class="s1">&#39;value2&#39;</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>如果设置了该变量必需传值，这时候默认值就无需设置了，需要注意是 props 对象中的属性名可以使用驼峰写法，但是在使用 v-bind 传值时，使用了驼峰写法的变量应该使用 - 代替，单词全部为小写，如下</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl">&#34;myCpn&#34; --&gt; &#34;my-cpn&#34;
</span></span></code></pre></div><h3 id="props-数据验证">props 数据验证</h3>
<p>在前面我们的 props 选项使用过数组写法，除了数组之外，还可以使用对象，当需要对 props 进行类型等验证时，就需要对象写法了</p>
<p>验证都支持如下几种数据类型</p>
<ol>
<li>String</li>
<li>Number</li>
<li>Boolean</li>
<li>Array</li>
<li>Object</li>
<li>Date</li>
<li>Function</li>
<li>Symbol</li>
</ol>
<p>使用数据验证可以对传入的值进行判断</p>
<h3 id="子传父">子传父</h3>
<p>子传父使用 $emit 来传输数据，还需要一个事件来决定何时向父组件发送数据，下面使用表单来演示</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">cpn</span> <span class="na">v-on:message</span><span class="o">=</span><span class="s">&#34;receive&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">cpn</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;mycpn&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="o">=</span><span class="s">&#34;text&#34;</span> <span class="na">v-on:input</span><span class="o">=</span><span class="s">&#34;send&#34;</span> <span class="p">/&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">temp</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vue</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">el</span><span class="o">:</span> <span class="s2">&#34;main&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">data</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">content</span><span class="o">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">methods</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">receive</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">this</span><span class="p">.</span><span class="nx">content</span> <span class="o">=</span> <span class="nx">value</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">components</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">cpn</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">template</span><span class="o">:</span> <span class="s2">&#34;#mycpn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">methods</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">send</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="k">this</span><span class="p">.</span><span class="nx">$emit</span><span class="p">(</span><span class="s2">&#34;message&#34;</span><span class="p">,</span> <span class="nx">event</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">value</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>在上方代码中子组件通过 input 事件调用定义好的 send 方法，在 $emit 中有两个参数，第一个是事件名称，第二个是传入的数据，定义好事件名称后，在 Vue 实例管理的 Dom 元素中，我们看到使用了 cpn 这个组件，在这个组件中我们使用定义好的事件 message ，然后值是一个方法 receive，这个方法定义在父组件中，也就是目前的 Vue 实例，这个方法有一个参数，是系统将之前 $emit 中的第二参数传了过来，这个使用一个形参变量来接收，然后为 Vue 实例中的变量 content 赋值</p>
<blockquote>
<p>总的来说，父组件向子组件传递数据使用 props 属性，而子组件向父组件传递数据使用 $emit</p>
<p>在真实开发中，Vue 实例和子组件的通信和父组件和子组件的通信过程是一样的</p>
</blockquote>
<h1 id="父子组件的访问方式">父子组件的访问方式</h1>
<p>有时候我们需要父组件直接访问子组件，子组件直接访问父组件，或则是子组件直接访问根组件，如下</p>
<ol>
<li>父组件访问子组件：使用 $children 或者 $refs</li>
<li>子组件访问父组件：使用 $parent</li>
<li>子组件访问根组件：使用 $root</li>
</ol>
<h3 id="children">$children</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">cpn</span><span class="p">&gt;&lt;/</span><span class="nt">cpn</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span> <span class="na">v-on:click</span><span class="o">=</span><span class="s">&#34;show&#34;</span><span class="p">&gt;</span>OK<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">temp</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vue</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">el</span><span class="o">:</span> <span class="s2">&#34;main&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">methods</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">show</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">$children</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">content</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">components</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">cpn</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">template</span><span class="o">:</span> <span class="s2">&#34;#mycpn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">data</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">content</span><span class="o">:</span> <span class="s2">&#34;Hello $children&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="p">};</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>使用 $children 会返回一个含有子组件的数组，通过下标进行选择，然后访问组件内的数据 data，及调用方法，打开控制台即可看到输出的信息，如果所有的子组件都需要遍历，使用 $children 是挺好的，但是只需要对其中一个确定的子组件进行操作时，使用下标进行选取，就有了不确定性，比如中间增加了一个子组件，这时数组的长度和下标就发生的改变，所以推荐使用 $refs，如下</p>
<h3 id="refs">$refs</h3>
<p>默认情况下访问 $refs 的话，是一个空数组，通过对子组件添加一个属性 ref ，后面跟上一个名称，这时，我们再访问 $refs ，就不再是一个空数组了，与 $children 不同的是，$children 是通过下标访问的，而 $refs 是通过 ref 后面定义的名称访问的，这样即使数组发生改变，也不会影响到对某个子组件的访问了，如下</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">cpn</span> <span class="na">ref</span><span class="o">=</span><span class="s">&#34;child&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">cpn</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">button</span> <span class="na">v-on:click</span><span class="o">=</span><span class="s">&#34;show&#34;</span><span class="p">&gt;</span>OK<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">temp</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vue</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">el</span><span class="o">:</span> <span class="s2">&#34;main&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">methods</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">show</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">$refs</span><span class="p">.</span><span class="nx">child</span><span class="p">.</span><span class="nx">content</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">components</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">cpn</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">template</span><span class="o">:</span> <span class="s2">&#34;#mycpn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">data</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">content</span><span class="o">:</span> <span class="s2">&#34;Hello $refs&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="p">};</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><h3 id="parent">$parent</h3>
<p>通过在子组件里定义了一个按钮，调用一个 show 方法，方法内使用 $parent 打印父组件的变量 content 和调用父组件的 show 方法，如下</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">cpn</span><span class="p">&gt;&lt;/</span><span class="nt">cpn</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">main</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span> <span class="na">id</span><span class="o">=</span><span class="s">&#34;mycpn&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">button</span> <span class="na">v-on:click</span><span class="o">=</span><span class="s">&#34;show&#34;</span><span class="p">&gt;</span>OK<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">temp</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Vue</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">  <span class="nx">el</span><span class="o">:</span> <span class="s2">&#34;main&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">data</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">content</span><span class="o">:</span> <span class="s2">&#34;Hello Father&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">components</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">cpn</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">template</span><span class="o">:</span> <span class="s2">&#34;#mycpn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">methods</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">show</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">$parent</span><span class="p">.</span><span class="nx">content</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><h3 id="root">$root</h3>
<p>如果父子组件之间嵌套的过多，想要在多层子组件里面直接访问根组件内的数据，可以将以上代码中 $parent 换为 $root，即可，用法如上</p>
<blockquote>
<p>后面我们会使用 Vue 脚手架，来组件化开发</p>
</blockquote>
</div>
                    <div class="post_footer">
                        
                        
                        <div id="link">
                            <p>本博客所有文章除特别声明外，均采用 CC BY-SA 3.0协议 。转载请注明出处！</p>
                            <p><span id="link_href"></span><i class="ri-file-copy-2-line link_btn"></i></p>
                        </div>
                        
                        <div class="meta">
                            <div class="info">
                                <span class="field tags">
                                    <i class="ri-price-tag-2-line"></i>
                                    
                                    <a href="https://awesome404.gitee.io/tags/vue2/">Vue2</a>
                                    
                                </span>
                            </div>
                        </div>
                        
                    </div>
                </div>
                
                
            </div>
        </div>
    </div>
    <a id="back_to_top" href="#" class="back_to_top"><i class="ri-arrow-up-s-line"></i></a>
    
<style>
  #hitokoto {
    overflow: hidden;
    margin: 0 auto;
    width: 80%;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 16px;
    color: #424242;
  }

  .footer {
    padding: 30px 0px;
  }
</style>

<footer class="footer">
  <p id="hitokoto">:D 获取中...</p>
</footer>

<script>
  fetch("https://v1.hitokoto.cn")
    .then((response) => response.json())
    .then((data) => {
      const hitokoto = document.getElementById("hitokoto");
      hitokoto.href = "https://hitokoto.cn/?uuid=" + data.uuid;
      hitokoto.innerText = data.hitokoto;
    })
    .catch((err) => err);
</script>

    <script src="https://awesome404.gitee.io/js/jquery-3.5.1.min.js"></script>
<link href="https://awesome404.gitee.io/css/fancybox.min.css" rel="stylesheet">
<script src="https://awesome404.gitee.io/js/fancybox.min.js"></script>
<script src="https://awesome404.gitee.io/js/zozo.js"></script>




</body>


<script>
    (function (){
        
        function handleIcon (remove, target){
            this.classList.remove(remove);
            this.classList.add(target);
        }

        let hrefEl = document.getElementById("link_href");
        let copyBtn = document.getElementsByClassName("link_btn")[0];
        if (hrefEl){
            hrefEl.innerText = `文章链接: ${location.href}`;
            
            copyBtn.onclick = (event) => {
                
                navigator.clipboard.writeText(`文章转载自: ${location.href}`)
                
                handleIcon.call(event.target, "ri-file-copy-2-line", "ri-check-line");
                let timer = setTimeout(() => {
                    handleIcon.call(event.target, "ri-check-line", "ri-file-copy-2-line");
                    clearTimeout(timer)
                }, 1000)
            }
        }
    })();
</script>
</html>